package com.ostrich.cloud.ostrichGoodsService.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.ostrich.cloud.common.result.PageResult;
import com.ostrich.cloud.common.result.Result;
import com.ostrich.cloud.ostrichDistributionService.client.DeliveryOrderClient;
import com.ostrich.cloud.ostrichDistributionService.client.param.OrderParam;
import com.ostrich.cloud.ostrichGoodsSercice.model.Dto.GrounpByDto;
import com.ostrich.cloud.ostrichGoodsService.common.exception.OstrichGoodsException;
import com.ostrich.cloud.ostrichGoodsService.common.exception.OstrichGoodsExceptionCode;
import com.ostrich.cloud.ostrichGoodsService.common.status.GrounpByStatus;
import com.ostrich.cloud.ostrichGoodsService.infra.mapper.GoodsMapper;
import com.ostrich.cloud.ostrichGoodsService.infra.mapper.GrounpGoodsMapper;
import com.ostrich.cloud.ostrichGoodsService.infra.model.Goods;
import com.ostrich.cloud.ostrichGoodsService.infra.model.GrounpBy;
import com.ostrich.cloud.ostrichGoodsService.infra.mapper.GrounpByMapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ostrich.cloud.ostrichGoodsService.infra.model.GrounpGoods;
import com.ostrich.cloud.ostrichGoodsService.service.GrounpByService;
import com.ostrich.cloud.ostrichGoodsService.service.component.WebSocketServer;
import com.ostrich.cloud.ostrichGoodsService.service.param.AddGrounpByParam;
import com.ostrich.cloud.ostrichOrderService.client.OrderManagerClient;
import com.ostrich.cloud.ostrichOrderService.client.param.AddGroupParam;
import com.ostrich.cloud.ostrichOrderService.model.dto.GroupCustomerDto;
import com.ostrich.cloud.ostrichUserService.client.CustomerMangerClient;
import lombok.extern.slf4j.Slf4j;
import org.apache.rocketmq.client.producer.SendCallback;
import org.apache.rocketmq.client.producer.SendResult;
import org.apache.rocketmq.spring.core.RocketMQTemplate;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.messaging.support.MessageBuilder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.RequestParam;

import javax.annotation.Resource;
import java.util.Date;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.concurrent.TimeUnit;

/**
 * <p>
 * 拼团表 服务实现类
 * </p>
 *
 * @author Lucas
 * @since 2022-11-03
 */
@Service
@Slf4j
public class GrounpByServiceImpl extends ServiceImpl<GrounpByMapper, GrounpBy> implements GrounpByService {

    @Resource
    private GrounpByMapper grounpByMapper;

    @Resource
    private GrounpGoodsMapper grounpGoodsMapper;

    @Resource
    private RedissonClient redissonClient;

    @Resource
    private OrderManagerClient orderManagerClient;
    @Resource
    private GoodsMapper goodsMapper;

    @Resource
    private RocketMQTemplate rocketMQTemplate;


    @Resource
    private CustomerMangerClient customerMangerClient;

    @Resource
    private DeliveryOrderClient deliveryOrderClient;
    @Override
    @Transactional
    public void addGrounpBy(AddGrounpByParam addGrounpByParam) {
        GrounpBy grounpBy =null;
        GrounpGoods grounpGoods = grounpGoodsMapper.selectById(addGrounpByParam.getGroundGoodsId());
        log.info("判断是发起拼团订单还是加入{}",addGrounpByParam);
        if(addGrounpByParam.getGrId()!=null){
            log.info("加入拼团");
            RLock lock = redissonClient.getLock("" + addGrounpByParam.getGrId());
            lock.lock(30, TimeUnit.SECONDS);
            grounpBy=grounpByMapper.selectById(addGrounpByParam.getGrId());
            Integer currentCount = grounpBy.getCurrentCount();
            Integer peopleCount = grounpBy.getPeopleCount();
            if(peopleCount==currentCount){
                lock.unlock();
                throw new OstrichGoodsException(OstrichGoodsExceptionCode.PARTICIPATE_IN_SPELL_GROUP_ERROR);
            }
            grounpBy.setPeopleCount(peopleCount+1);
            grounpByMapper.updateById(grounpBy);
            log.info("加入拼团成功{}",grounpBy);
            lock.unlock();

        }else {
            log.info("发起拼团");

            if(grounpGoods==null){
                throw new OstrichGoodsException(OstrichGoodsExceptionCode.GOODS_GET_EXCEPTION);
            }
            if(grounpGoods.getStock()==0){
                throw new OstrichGoodsException(OstrichGoodsExceptionCode.STOCK_ZERO_EXCEPTION);
            }
            grounpBy = BeanUtil.copyProperties(addGrounpByParam, GrounpBy.class);
            grounpBy.setPeopleCount(1);
            grounpBy.setAddTime(new Date());
            grounpBy.setCurrentCount(grounpGoods.getPeopleCount());
            grounpBy.setStatus(GrounpByStatus.GO_ON);
            grounpByMapper.insert(grounpBy);
            grounpGoods.setStock(grounpGoods.getStock()-grounpGoods.getPeopleCount());
            if(grounpGoods.getStock()-grounpGoods.getPeopleCount()<0){
                throw new OstrichGoodsException(OstrichGoodsExceptionCode.GOODS_GET_EXCEPTION);
            }
            grounpGoods.setSale(grounpGoods.getSale()+grounpGoods.getPeopleCount());
            log.info("修改拼团商品库存");
            grounpGoodsMapper.updateById(grounpGoods);
            log.info("修改成功");
            rocketMQTemplate.asyncSend("Grounp_group", MessageBuilder.withPayload(grounpBy).build(), new SendCallback() {
                @Override
                public void onSuccess(SendResult sendResult) {
                    log.info("开始发送消息{}",sendResult);
                }

                @Override
                public void onException(Throwable throwable) {

                }
            },1000,18);

        }

        Goods goods = goodsMapper.selectById(grounpGoods.getGoodsId());
        AddGroupParam param=BeanUtil.copyProperties(goods,AddGroupParam.class);
        param.setTotalAmount(goods.getGoodsPrice());
        param.setPrice(grounpGoods.getPrice());
        param.setGroupbySn(grounpBy.getGrId());
        param.setNotes("拼团订单");
        param.setCustomerLocationId(addGrounpByParam.getCustomerLocationId());
        log.info("生成订单{}",param);
        orderManagerClient.createGroup(param);
        log.info("生成成功");
        if(grounpBy.getCurrentCount()==grounpBy.getPeopleCount()){
            GrounpByDto grounpByDto = BeanUtil.copyProperties(grounpBy, GrounpByDto.class);
            grounpBy.setStatus(GrounpByStatus.SUCCESS);
            grounpByMapper.updateById(grounpBy);
            log.info("获取订单信息");
            List<GroupCustomerDto> groupCustomer = orderManagerClient.getGroupCustomer(grounpBy.getGrId());
            log.info("生成成功");
            for (GroupCustomerDto g:groupCustomer){

                Integer customer = g.getCustomer();
                log.info("获取用户信息");
                Result cusMessage = customerMangerClient.getCusMessage();
                log.info("获取成功：{}",cusMessage);
                LinkedHashMap<String, Integer> data = (LinkedHashMap<String, Integer>) cusMessage.getData();
                Long mobile = new Long(data.get("mobile"));
                OrderParam orderParam = new OrderParam();
                orderParam.setCustomerPhone(mobile);
                orderParam.setBusinessmanId(g.getBusinessmanId());
                orderParam.setCreateTime(new Date());
                orderParam.setCustomerLocationId(g.getCustomerLocationId());
                orderParam.setDeliveryNumber(g.getOrderNo());
                log.info("orderParam>>>>>>>>{}",orderParam);
                deliveryOrderClient.orderAdd(orderParam);
                log.info("生成配送订单成功");

            }
            log.info("拼团成功：{}",grounpBy);
            WebSocketServer.sendInfo(grounpByDto,goods.getBusinessmanId()+"");


        }



    }

    @Override
    public List<GrounpByDto> selectGrounpBy(Integer groundGoodsId) {

        QueryWrapper<GrounpBy> wrapper = new QueryWrapper<>();
        wrapper.eq("ground_goods_id",groundGoodsId);
        List<GrounpBy> grounpBIES = grounpByMapper.selectList(wrapper);

        List<GrounpByDto> grounpByDtos = BeanUtil.copyToList(grounpBIES, GrounpByDto.class);

        return grounpByDtos;
    }


}
